package sistema_de_arquivos;




import java.util.ArrayList;
import java.util.Date;


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author modesto
 */
public class Diretorio extends ArquivoGenerico {
    public ArrayList<Arquivo> filhos_arquivo;
    public ArrayList<Diretorio> filhos_diretorio;

    public Diretorio() {
        super();
        this.filhos_arquivo = new ArrayList<Arquivo>();
        this.filhos_diretorio = new ArrayList<Diretorio>();
    }
    
    public Diretorio(String nome, boolean escrita, boolean leitura, int bloco_inicio)
    {
        super(nome, false, escrita, leitura, 4096, bloco_inicio);
        this.filhos_arquivo = new ArrayList<Arquivo>();
        this.filhos_diretorio = new ArrayList<Diretorio>();
        this.erro.codigo = 0;
    }

    public Diretorio(ArrayList<Arquivo> filhos_arquivo, ArrayList<Diretorio> filhos_diretorio, String nome, Date data_criacao, int tamanho, boolean executavel, boolean escrita, boolean leitura, int bloco_inicio) {
        super(nome, data_criacao, tamanho, executavel, escrita, leitura, bloco_inicio);
        this.filhos_arquivo = filhos_arquivo;
        this.filhos_diretorio = filhos_diretorio;
    }
    
    /**
     * Adiciona um arquivo ao diretorio
     * @param nome -> nome do arquivo a ser adicionado
     * @param executavel -> permissao de execucao habilitada ou nao
     * @param escrita -> permissao de escrita habilitada ou nao
     * @param leitura -> permissao de leitura habilitada ou nao
     * @param bloco_inicio -> bloco de localizacao no odisco
     * @return Objeto Erro indicando o status de saida
     */
    
    public Erro addFilhoArquivo(String nome, boolean executavel, boolean escrita, boolean leitura, int tamanho, int bloco_inicio)
    {
        Erro erro = new Erro();
        Arquivo arquivo = new Arquivo(nome, executavel, escrita, leitura, tamanho, bloco_inicio);
        arquivo.pai = this;
        
        if (!this.escrita)
            return new Erro(3, this.nome + ": Sem permissao de escrita.");
        
        for (int i = 0; i < filhos_arquivo.size(); i++)
        {
            if (filhos_arquivo.get(i).nome.equalsIgnoreCase(nome))
            {
                erro.codigo = 5;
                erro.mensagem = "Ja existe um arquivo com esse nome.";
                return erro;
            }
        }
        
        filhos_arquivo.add(arquivo);
        
        return arquivo.erro;
    }
    
    /**
     * Remove um arquivo do diretorio
     * @param nome  -> Nome do arquivo a ser removido
     * @return  -> Objeto erro com o status de saida
     */
    
    public Erro delFilhoArquivo(String nome)
    {
        Arquivo arquivo;
        Erro erro = new Erro();
        
        if (!this.escrita)
            return new Erro(3, this.nome + ": Sem permissao de escrita.");
        
        for (int i = 0; i < filhos_arquivo.size(); i++)
        {
            arquivo = filhos_arquivo.get(i);
            
            if (arquivo.nome.equalsIgnoreCase(nome))
            {
                filhos_arquivo.remove(i);
                erro.codigo = 0;
                return erro;
            }
        }
        
        erro.codigo = 6;
        erro.mensagem = "Arquivo inexistente.";
        
        return erro;
    }
    
    /**
     * Adiciona um diretorio no diretorio atual
     * @param nome -> Nome do diretorio a ser criado
     * @param escrita -> Permissao de escrita habilitada ou nao
     * @param leitura -> Permissao de leitura habilitada ou nao
     * @param bloco_inicio -> Bloco de localizacao no disco
     * @return -> Objeto erro com status de saida
     */
    
    public Erro addFilhoDiretorio(String nome, boolean escrita, boolean leitura, int bloco_inicio)
    {
        Erro erro = new Erro();
        Diretorio diretorio = new Diretorio(nome, escrita, leitura, bloco_inicio);
        diretorio.pai = this;
        
        if (!this.escrita)
            return new Erro(3, this.nome + ": Sem permissao de escrita.");
        
        for (int i = 0; i < filhos_diretorio.size(); i++)
        {
            if (filhos_diretorio.get(i).nome.equalsIgnoreCase(nome))
            {
                erro.codigo = 5;
                erro.mensagem = "Ja existe um diretorio com esse nome.";
                return erro;
            }
        }
        
        if (diretorio.erro.codigo == 0)
            this.filhos_diretorio.add(diretorio);
        
        return diretorio.erro;     
    }
    
    /**
     * Remove um diretorio filho do diretorio atual
     * @param nome -> Nome do diretorio a ser removido
     * @return -> Objeto erro com informacoes de saida
     */
    public Erro delFilhoDiretorio(String nome)
    {
        Erro erro = new Erro();
        
        if (!this.escrita)
            return new Erro(3, this.nome + ": Sem permissao de escrita.");
        
        for (Diretorio dir: this.filhos_diretorio)
        {
            if (dir.nome.equalsIgnoreCase(nome))
            {
                this.filhos_diretorio.remove(dir);
                break;
            }
        }
        
        erro.codigo = 6;
        erro.mensagem = "Diretorio nao existe";
        return erro;
    }
    
    public ArrayList<String> listaFilhosArquivo()
    {
        ArrayList<String> retorno = new ArrayList<String>();
        
        for (int i = 0; i < this.filhos_arquivo.size(); i++)
        {
            retorno.add(filhos_arquivo.get(i).nome);
        }
        
        return retorno;
    }
    
    
    public ArrayList<String> listaFilhosDiretorio()
    {
        ArrayList<String> retorno = new ArrayList<String>();
        
        for (int i = 0; i < this.filhos_diretorio.size(); i++)
        {
            retorno.add(filhos_diretorio.get(i).nome);
        }
        
        return retorno;
    }
    
    public boolean diretorioExiste(String nome)
    {
        
        for (Diretorio dir: this.filhos_diretorio)
        {
            if (dir.nome.equalsIgnoreCase(nome))
                return true;
        }
        
        return false;
    }
    
    public boolean arquivoExiste(String nome)
    {
        for (Arquivo arq: this.filhos_arquivo)
        {
            if (arq.nome.equalsIgnoreCase(nome))
                    return true;
        }
        
        return false;
    }
    
    public Diretorio getDiretorio(String nome)
    {
        for (Diretorio dir: this.filhos_diretorio)
        {
            if (dir.nome.equalsIgnoreCase(nome))
                return dir;
        }
        
        return null;
    }
    
    public Arquivo getArquivo(String nome)
    {
        for (Arquivo arq: this.filhos_arquivo)
        {
            if (arq.nome.equalsIgnoreCase(nome))
                return arq;
        }
        
        return null;
    }
    
    public Diretorio getDiretorioRecursivo(String caminho)
    {
        Diretorio cur_dir = this;
        int i;
        String arvore[];
        
        if (caminho.isEmpty())
            return null;
        
        arvore = caminho.split("/");
        i = (caminho.charAt(0) == '/') ? 1 : 0;
        
        for (; i < arvore.length; i++)
         if (!cur_dir.diretorioExiste(arvore[i]))
             return null;
         else
             cur_dir = cur_dir.getDiretorio(arvore[i]);
        
        return cur_dir;        
    }

    public String find (int dir_index, String nome)
    {

     return null;                   
    }
    
    
    public String pwd()
    {
        ArrayList <String> dir_tree = new ArrayList<String>();
        String caminho = "/";
        
        for (Diretorio cur_dir = this; cur_dir.pai != null; cur_dir = (Diretorio)cur_dir.pai)
        {
            //System.out.println(this.nome);
            dir_tree.add(cur_dir.nome);
        }
        
        for (int i = dir_tree.size() - 1; i >= 0; i--)
        {
            caminho = caminho + dir_tree.get(i);
            
            caminho += (i == 0) ? "" : "/";
        }
        
        return caminho;
    }
    
}
